package com.zxct.wyserver.util;

import com.socks.library.KLog;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by Wanxu on 2016/11/28.
 * 签名算法工具类
 */

public class SignatureUtils {

    //SHA1 加密实例
    public static String encryptToSHA(String info) {
        byte[] digesta = null;
        try {
            // 得到一个SHA-1的消息摘要
            MessageDigest alga = MessageDigest.getInstance("SHA-1");
            // 添加要进行计算摘要的信息
            alga.update(info.getBytes());
            // 得到该摘要
            digesta = alga.digest();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        // 将摘要转为字符串
        String rs = byte2hex(digesta);
        return rs;
    }

    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs;
    }

    //对上传的参数进行排序,并在结尾处添加appsecret
    public static Map<String,String> urlMap(Map<String,String> map, String secret){
        List<Map.Entry<String,String>> mappingList = null;
        //通过Arraylist构造函数把map.entrySet()转换成list
        mappingList = new ArrayList<Map.Entry<String, String>>(map.entrySet());
        //通过比较器实现比较排序
        Collections.sort(mappingList, new Comparator<Map.Entry<String, String>>() {
            public int compare(Map.Entry<String,String> mapping1,Map.Entry<String,String> mapping2){
                //先转为小写,再排序
                return mapping1.getKey().toLowerCase().compareTo(mapping2.getKey().toLowerCase());
            }
        });
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(secret);
        for(Map.Entry<String,String> mapping: mappingList){
            KLog.d(mapping.getKey()+":"+mapping.getValue());
            stringBuffer.append(mapping.getKey().toLowerCase()).append(mapping.getValue());
        }

        KLog.d("url---"+stringBuffer.toString());
        KLog.d("sha1url---"+encryptToSHA(stringBuffer.toString()));

        map.put("appsign",encryptToSHA(stringBuffer.toString()));
        return map;
    }

    public static String MD5(String pwd) {
        //用于加密的字符
        char md5String[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F' };
        try {
            //使用平台的默认字符集将此 String 编码为 byte序列，并将结果存储到一个新的 byte数组中
            byte[] btInput = pwd.getBytes();

            //信息摘要是安全的单向哈希函数，它接收任意大小的数据，并输出固定长度的哈希值。
            MessageDigest mdInst = MessageDigest.getInstance("MD5");

            //MessageDigest对象通过使用 update方法处理数据， 使用指定的byte数组更新摘要
            mdInst.update(btInput);

            // 摘要更新之后，通过调用digest（）执行哈希计算，获得密文
            byte[] md = mdInst.digest();

            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {   //  i = 0
                byte byte0 = md[i];  //95
                str[k++] = md5String[byte0 >>> 4 & 0xf];    //    5
                str[k++] = md5String[byte0 & 0xf];   //   F
            }

            //返回经过加密后的字符串
            return new String(str);

        } catch (Exception e) {
            return null;
        }
    }

    public static int getSecondTimestampTwo(Date date){
        if (null == date) {
            return 0;
        }
        String timestamp = String.valueOf(date.getTime()/1000);
        return Integer.valueOf(timestamp);
    }

    public static String setEncrypt(String password, String cstrKey) {
        //int[] snNum = new int[password.length()];
        char[] snNum = new char[password.length()];
        String result = "";
        for (int i = 0, j = 0; i < password.length(); i++, j++) {
            if (j == cstrKey.length())
                j = 0;
            //snNum[i] = password.charAt(i) ^ cstrKey.charAt(j) ^ (1 / (i + 1));
            snNum[i] = (char) (password.charAt(i) ^ cstrKey.charAt(j) ^ (1 / (i + 1)));
            result += (char) snNum[i];
        }
        return result;
    }

    public static String getEncrypt(String password, String cstrKey) {
        char[] snNum = new char[password.length()];
        String result = "";
        for (int i = 0, j = 0; i < password.length(); i++, j++) {
            if (j == cstrKey.length())
                j = 0;
            char n = password.charAt(i);
            snNum[i] = (char) (n ^ cstrKey.charAt(j) ^ (1 / (i + 1)));
            result += snNum[i];
        }
        return result;
    }
}
